#include "Order.h"
#include "User.h" // User::deduct 等需要 User 对象
#include <iostream>
#include <random> // For a slightly better unique ID part
#include <sstream>

std::string Order::generateOrderId()
{
    auto now = std::chrono::system_clock::now();
    auto epoch = now.time_since_epoch();
    auto value = std::chrono::duration_cast<std::chrono::milliseconds>(epoch);

    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> distrib(100, 999);

    return "ORD" + std::to_string(value.count()) + std::to_string(distrib(gen));
}

Order::Order(int custId, const ShoppingCart &cart, ProductController &productCtrl)
    : customerId(custId), totalAmount(0.0), status(OrderStatus::FAILED_STOCK_FREEZE), orderTime(std::chrono::system_clock::now())
{
    this->orderId = generateOrderId();

    if (cart.isEmpty())
    {
        std::cerr << "错误：购物车为空，无法创建订单。" << std::endl;
        this->status = OrderStatus::CANCELLED; // 或其他表示空订单的状态
        return;
    }

    std::vector<OrderItem> tempOrderItems;
    std::vector<std::pair<std::string, int>> itemsToFreezeSuccessfully; // productId, quantity

    // 1. 检查库存并将商品信息复制到订单项
    std::vector<CartItem> totalCartItems = cart.getItems();
    for (const auto &cartItem : totalCartItems)
    {
        if (cartItem.quantity <= 0)
        {
            std::cerr << "错误：购物车中的商品 " << cartItem.product->getName() << " 数量无效，无法创建订单。" << std::endl;
            continue; // 跳过无效数量的商品
        }
        Product *product = productCtrl.findProductById(cartItem.product->getId());

        if (!product)
        {
            std::cerr << "错误：购物车中的商品 " << cartItem.product->getName() << " 未找到。订单创建失败。" << std::endl;
            // 如果一个商品找不到，整个订单创建失败，需要回滚已冻结的（如果有）
            // 此处简化：直接返回，状态已是 FAILED_STOCK_FREEZE
            for (const auto &frozen : itemsToFreezeSuccessfully)
            {
                Product *p_rollback = productCtrl.findProductById(frozen.first);
                if (p_rollback)
                    p_rollback->unfreezeStock(frozen.second);
            }
            productCtrl.saveProducts(); // 保存回滚的状态
            this->items.clear();        // 清空订单项
            this->totalAmount = 0;
            return;
        }
        if (product->getAvailableQuantity() < cartItem.quantity)
        {
            std::cerr << "错误：商品 \"" << product->getName() << "\" 库存不足 (需 "
                      << cartItem.quantity << ",剩 " << product->getAvailableQuantity() << ")。订单创建失败。" << std::endl;
            for (const auto &frozen : itemsToFreezeSuccessfully)
            { // 回滚之前成功冻结的
                Product *p_rollback = productCtrl.findProductById(frozen.first);
                if (p_rollback)
                    p_rollback->unfreezeStock(frozen.second);
            }
            productCtrl.saveProducts();
            this->items.clear();
            this->totalAmount = 0;
            return;
        }

        OrderItem oi;
        oi.productId = product->getId();
        oi.productName = product->getName(); // 快照
        oi.quantity = cartItem.quantity;
        oi.unitPrice = product->getPrice(); // 当前实际价格作为成交价
        oi.sellerId = product->getSellerId();
        tempOrderItems.push_back(oi);
        this->totalAmount += oi.unitPrice * oi.quantity;
    }

    // 2. 尝试冻结所有商品的库存
    bool allFrozen = true;
    for (const auto &oi : tempOrderItems)
    {
        Product *product = productCtrl.findProductById(oi.productId);
        // product 应该能找到，因为上面检查过了
        if (product && product->freezeStock(oi.quantity))
        {
            productCtrl.saveProducts(); // 保存商品状态
            itemsToFreezeSuccessfully.push_back({oi.productId, oi.quantity});
        }
        else
        {
            allFrozen = false;
            std::cerr << "错误：冻结商品 \"" << oi.productName << "\" 库存失败。" << std::endl;
            break;
        }
    }

    if (allFrozen)
    {
        this->items = tempOrderItems;
        this->status = OrderStatus::UNPAID;
        productCtrl.saveProducts(); // 保存所有商品冻结后的状态
        std::cout << "订单 " << this->orderId << " 创建成功，总金额: ¥" << std::fixed << std::setprecision(2) << this->totalAmount << "。商品库存已冻结。" << std::endl;
    }
    else
    {
        // 回滚已成功冻结的库存
        for (const auto &frozenItemPair : itemsToFreezeSuccessfully)
        {
            Product *productToUnfreeze = productCtrl.findProductById(frozenItemPair.first);
            if (productToUnfreeze)
            {
                productToUnfreeze->unfreezeStock(frozenItemPair.second);
            }
        }
        productCtrl.saveProducts(); // 保存回滚后的状态
        this->items.clear();        // 订单无效
        this->totalAmount = 0;
        this->status = OrderStatus::FAILED_STOCK_FREEZE; // 明确失败状态
        std::cerr << "订单创建失败：部分商品库存无法冻结。" << std::endl;
    }
}

// Order.cpp 或你的实现文件

// 【新增】Order 的序列化方法
json Order::toJson() const
{
    json j;
    j["orderId"] = this->orderId;
    j["customerId"] = this->customerId;
    j["totalAmount"] = this->totalAmount;
    j["status"] = orderStatusToString(this->status);
    // 将时间点转换为自纪元以来的秒数进行存储
    j["orderTime"] = std::chrono::duration_cast<std::chrono::seconds>(this->orderTime.time_since_epoch()).count();

    json j_items = json::array();
    for (const auto &item : this->items)
    {
        json j_item;
        j_item["productId"] = item.productId;
        j_item["productName"] = item.productName;
        j_item["quantity"] = item.quantity;
        j_item["unitPrice"] = item.unitPrice;
        j_item["sellerId"] = item.sellerId;
        j_items.push_back(j_item);
    }
    j["items"] = j_items;
    return j;
}

// 【新增】一个辅助函数，用于将字符串状态转回 enum (Order.cpp 内部使用)
OrderStatus stringToOrderStatus(const std::string &statusStr)
{
    if (statusStr == "已支付" || statusStr == "PAID")
        return OrderStatus::PAID;
    if (statusStr == "已取消" || statusStr == "CANCELLED")
        return OrderStatus::CANCELLED;
    if (statusStr == "库存冻结失败" || statusStr == "FAILED_STOCK_FREEZE")
        return OrderStatus::FAILED_STOCK_FREEZE;
    if (statusStr == "支付失败" || statusStr == "PAYMENT_FAILED")
        return OrderStatus::PAYMENT_FAILED;
    return OrderStatus::UNPAID; // 默认为未支付
}

// 【新增】Order 从 JSON 反序列化的构造函数
Order::Order(const json &j_order)
{
    this->orderId = j_order.at("orderId").get<std::string>();
    this->customerId = j_order.at("customerId").get<int>();
    this->totalAmount = j_order.at("totalAmount").get<double>();
    this->status = stringToOrderStatus(j_order.at("status").get<std::string>());

    // 从秒数恢复时间点
    long long seconds_since_epoch = j_order.at("orderTime").get<long long>();
    this->orderTime = std::chrono::system_clock::time_point(std::chrono::seconds(seconds_since_epoch));

    const json &j_items = j_order.at("items");
    for (const auto &j_item : j_items)
    {
        OrderItem oi;
        oi.productId = j_item.at("productId").get<std::string>();
        oi.productName = j_item.at("productName").get<std::string>();
        oi.quantity = j_item.at("quantity").get<int>();
        oi.unitPrice = j_item.at("unitPrice").get<double>();
        oi.sellerId = j_item.at("sellerId").get<int>();
        this->items.push_back(oi);
    }
}

// Getters
const std::string &Order::getOrderId() const { return orderId; }
int Order::getCustomerId() const { return customerId; }
const std::vector<Order::OrderItem> &Order::getItems() const { return items; }
double Order::getTotalAmount() const { return totalAmount; }
OrderStatus Order::getStatus() const { return status; }

std::string Order::getOrderTimeString() const
{
    std::time_t time_now = std::chrono::system_clock::to_time_t(orderTime);
    std::tm tm_buf;
// localtime_s is safer on Windows, otherwise use localtime
#if defined(_WIN32) || defined(_WIN64)
    localtime_s(&tm_buf, &time_now);
#else
    tm_buf = *localtime(&time_now);
#endif
    std::ostringstream oss;
    oss << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S");
    return oss.str();
}

void Order::setStatus(OrderStatus newStatus)
{
    this->status = newStatus;
}

// void Order::displayBriefInfo(int index) const
// {
//     std::ostringstream priceStream;
//     priceStream << "¥" << std::fixed << std::setprecision(2) << totalAmount;

//     std::cout << std::left
//               << std::setw(5) << index
//               << std::setw(30) << orderId
//               << std::setw(25) << getOrderTimeString()
//               << std::setw(15) << priceStream.str()
//               << std::setw(15) << orderStatusToString(status);
//     for (auto &item : items)
//     {
//         std::cout << std::setw(10) << item.productName;
//         break; // 只显示第一个商品ID
//     }
//     std::cout << std::endl;
// }

// void Order::displayOrderDetails() const
// {
//     std::cout << "\n--- 订单详情 ---" << std::endl;
//     std::cout << "订单ID: " << orderId << std::endl;
//     std::cout << "下单时间: " << getOrderTimeString() << std::endl;
//     std::cout << "订单状态: " << orderStatusToString(status) << std::endl;
//     std::cout << "总金额: ¥" << std::fixed << std::setprecision(2) << totalAmount << std::endl;
//     std::cout << "商品列表:" << std::endl;
//     std::cout << std::left << std::setw(10) << "商品ID"
//               << std::setw(30) << "名称"
//               << std::setw(10) << "数量"
//               << std::setw(15) << "成交单价"
//               << std::setw(10) << "卖家ID" << std::endl;
//     std::cout << "------------------------------------------------------------------------" << std::endl;
//     for (const auto &item : items)
//     {
//         std::cout << std::left << std::setw(10) << item.productId
//                   << std::setw(30) << item.productName
//                   << std::setw(10) << item.quantity
//                   << std::setw(15) << std::fixed << std::setprecision(2) << item.unitPrice
//                   << std::setw(10) << item.sellerId << std::endl;
//     }
//     std::cout << "------------------------------------------------------------------------" << std::endl;
// }

bool Order::processPayment(User &customer, UserController &userCtrl, ProductController &productCtrl)
{
    if (status != OrderStatus::UNPAID)
    {
        std::cout << "订单 " << orderId << " 状态不是未支付，无法处理支付。" << std::endl;
        return false;
    }

    if (customer.getId() != this->customerId)
    {
        std::cout << "错误：尝试支付的用户与订单用户不符。" << std::endl;
        return false;
    }

    // 1. 顾客扣款 (User::deduct 会调用 userCtrl.updateUserBalance 保存)
    if (!userCtrl.withdrawBalance(customer.getId(), this->totalAmount))
    {
        std::cout << "支付失败：顾客余额不足或扣款失败。" << std::endl;
        this->status = OrderStatus::PAYMENT_FAILED;
        return false;
    }
    else
    {
        customer.deduct(this->totalAmount); // 更新顾客余额
    }

    // 2. 将金额转入各商家账户
    // 后期变为向另一方发送信息。
    // 为简化，如果任何一个商家充值失败，这里不进行复杂回滚，实际系统需要事务处理
    bool allSellersCredited = true;
    for (const auto &item : this->items)
    {
        double itemTotal = item.unitPrice * item.quantity;
        if (!userCtrl.rechargeBalance(item.sellerId, itemTotal))
        { // rechargeBalance 保存数据
            std::cerr << "严重错误：订单 " << orderId << "，商品 " << item.productId
                      << " 的款项未能成功转给商家ID " << item.sellerId << "。" << std::endl;
            // 理论上这里应该回滚顾客的扣款，但这很复杂。
            // 简单处理：标记支付失败，需要人工介入。
            allSellersCredited = false;
            // 不立即返回，尝试为其他卖家充值
        }
        else
        {
            std::cout << "订单 " << orderId << ": ¥" << itemTotal << " 已转入商家ID " << item.sellerId << " 账户。" << std::endl;
        }
    }

    if (!allSellersCredited)
    {
        std::cerr << "订单 " << orderId << " 支付处理异常：部分商家未能收到款项。请联系客服。" << std::endl;
        // 顾客的钱已经被扣了，这是一个问题状态。
        // 可以尝试回滚顾客扣款，或者标记订单为特殊错误状态
        // customer.recharge(this->totalAmount, userCtrl); // 尝试回滚，但可能导致其他问题
        this->status = OrderStatus::PAYMENT_FAILED; // 标记支付失败
        return false;
    }

    // 3. 确认销售，更新商品实际库存 (总库存和冻结库存都会减少)
    for (const auto &item : this->items)
    {
        Product *product = productCtrl.findProductById(item.productId);
        if (product)
        {
            if (!product->confirmSale(item.quantity))
            {
                std::cerr << "严重错误：订单 " << orderId << "，商品 " << item.productId
                          << " 确认销售失败 (库存更新错误)。" << std::endl;
                // 这是一个非常严重的问题，钱已转，但库存没正确更新
                // 可能需要标记订单并人工处理
            }
        }
        else
        {
            std::cerr << "严重错误：订单 " << orderId << "，支付后找不到商品 " << item.productId << " 以确认销售。" << std::endl;
        }
    }
    productCtrl.saveProducts(); // 保存商品销售后的状态

    this->status = OrderStatus::PAID;
    return true;
}

void Order::cancelOrder(ProductController &productCtrl)
{
    if (status == OrderStatus::PAID)
    {
        std::cout << "订单 " << orderId << " 已支付，无法直接取消。请联系客服处理退款。" << std::endl;
        return;
    }
    if (status == OrderStatus::CANCELLED)
    {
        std::cout << "订单 " << orderId << " 已经是取消状态。" << std::endl;
        return;
    }

    // 解冻之前为此订单冻结的库存
    // 只有在订单创建时成功冻结了库存（即状态不是FAILED_STOCK_FREEZE初始状态）才需要解冻
    if (status == OrderStatus::UNPAID || status == OrderStatus::PAYMENT_FAILED)
    { // PAYMENT_FAILED也可能需要解冻
        bool allUnfrozen = true;
        if (!items.empty())
        { // 确保有商品项才去解冻
            std::cout << "正在为订单 " << orderId << " 解冻商品库存..." << std::endl;
            for (const auto &item : this->items)
            {
                Product *product = productCtrl.findProductById(item.productId);
                if (product)
                {
                    if (!product->unfreezeStock(item.quantity))
                    {
                        std::cerr << "警告：订单 " << orderId << "，商品 " << item.productId
                                  << " 解冻库存操作未按预期完成。" << std::endl;
                        // unfreezeStock 内部会处理数量问题
                        allUnfrozen = false;
                    }
                }
                else
                {
                    std::cerr << "警告：订单 " << orderId << "，取消时找不到商品 " << item.productId << " 以解冻库存。" << std::endl;
                    allUnfrozen = false;
                }
            }
            if (allUnfrozen)
                std::cout << "库存解冻完成。" << std::endl;
            else
                std::cout << "库存解冻过程存在警告，请检查商品状态。" << std::endl;
            productCtrl.saveProducts(); // 保存商品解冻后的状态
        }
    }

    this->status = OrderStatus::CANCELLED;
    std::cout << "订单 " << orderId << " 已取消。" << std::endl;
}